package com.ikingtech.platform.service.sms.controller;

import com.ikingtech.framework.sdk.context.exception.FrameworkException;
import com.ikingtech.framework.sdk.core.response.R;
import com.ikingtech.framework.sdk.sms.api.SmsApi;
import com.ikingtech.framework.sdk.sms.embedded.SmsConfig;
import com.ikingtech.framework.sdk.sms.embedded.SmsRequestBuilder;
import com.ikingtech.framework.sdk.sms.embedded.SmsSendArgs;
import com.ikingtech.framework.sdk.sms.embedded.properties.SmsProperties;
import com.ikingtech.framework.sdk.sms.model.SmsDTO;
import com.ikingtech.framework.sdk.sms.model.SmsQueryParamDTO;
import com.ikingtech.framework.sdk.sms.model.SmsSendMessageParamDTO;
import com.ikingtech.framework.sdk.sms.model.SmsTemplateDTO;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.framework.sdk.web.annotation.ApiController;
import com.ikingtech.platform.service.sms.entity.SmsDO;
import com.ikingtech.platform.service.sms.exception.SmsExceptionInfo;
import com.ikingtech.platform.service.sms.service.SmsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * @author tie yan
 */
@Slf4j
@RequiredArgsConstructor
@ApiController(value = "/sms", name = "短信管理", description = "短信管理")
public class SmsController implements SmsApi {

    private final SmsService service;

    private final SmsRequestBuilder smsRequestBuilder;

    private final SmsProperties properties;

    @Override
    public R<String> add(SmsDTO sms) {
        if (Boolean.TRUE.equals(this.service.nameExist(sms.getName()))) {
            throw new FrameworkException(SmsExceptionInfo.DUPLICATE_SMS_NAME);
        }
        if (Boolean.TRUE.equals(this.service.appIdExist(sms.getAppId()))) {
            throw new FrameworkException(SmsExceptionInfo.DUPLICATE_SMS_APP_ID);
        }

        SmsDO entity = Tools.Bean.copy(sms, SmsDO.class);
        entity.setId(Tools.Id.uuid());
        this.service.save(entity);
        return R.ok(entity.getId());
    }

    @Override
    public R<Object> delete(String id) {
        this.service.removeById(id);
        return R.ok();
    }

    @Override
    public R<Object> update(SmsDTO sms) {
        if (!Boolean.TRUE.equals(this.service.exist(sms.getId()))) {
            throw new FrameworkException(SmsExceptionInfo.SMS_NOT_FOUND);
        }
        if (Boolean.TRUE.equals(this.service.nameExist(sms.getId(), sms.getName()))) {
            throw new FrameworkException(SmsExceptionInfo.DUPLICATE_SMS_NAME);
        }
        if (Boolean.TRUE.equals(this.service.appIdExist(sms.getId(), sms.getAppId()))) {
            throw new FrameworkException(SmsExceptionInfo.DUPLICATE_SMS_APP_ID);
        }

        this.service.updateById(Tools.Bean.copy(sms, SmsDO.class));
        return R.ok();
    }

    @Override
    public R<List<SmsDTO>> page(SmsQueryParamDTO queryParam) {
        return R.ok(this.service.listPage(queryParam).convert(entity -> Tools.Bean.copy(entity, SmsDTO.class)));
    }

    @Override
    public R<List<SmsDTO>> all() {
        return this.all(new SmsQueryParamDTO());
    }

    @Override
    public R<List<SmsDTO>> all(SmsQueryParamDTO queryParam) {
        List<SmsDTO> result = Tools.Coll.convertList(this.service.listBySupportTemplate(queryParam.getSupportTemplate()), entity -> Tools.Bean.copy(entity, SmsDTO.class));
        result.addAll(Tools.Coll.convertList(this.properties.getPlatform(), platform -> null == queryParam.getSupportTemplate() || platform.getSupportTemplate().equals(queryParam.getSupportTemplate()), platform -> {
            SmsDTO sms = Tools.Bean.copy(platform, SmsDTO.class);
            sms.setId(Tools.Id.uuid());
            sms.setCode(platform.getId());
            return sms;
        }));
        return R.ok(result);
    }

    @Override
    public R<SmsDTO> detail(String id) {
        SmsDO entity = this.service.getById(id);
        if (null == entity) {
            throw new FrameworkException(SmsExceptionInfo.SMS_NOT_FOUND);
        }
        return R.ok(Tools.Bean.copy(entity, SmsDTO.class));
    }

    @Override
    public R<Object> send(SmsSendMessageParamDTO sendMessageParam) {
        this.smsRequestBuilder.build(this.loadConfig(sendMessageParam.getSmsId()))
                .send(SmsSendArgs.builder()
                        .templateId(sendMessageParam.getTemplateId())
                        .content(sendMessageParam.getContent())
                        .params(sendMessageParam.getParams())
                        .phone(sendMessageParam.getPhone())
                        .build());
        return R.ok();
    }

    @Override
    public R<List<SmsTemplateDTO>> listTemplate(String smsId) {
        return R.ok(Tools.Coll.convertList(this.smsRequestBuilder.build(this.loadConfig(smsId)).listTemplate(), templateInfo -> {
            SmsTemplateDTO template = new SmsTemplateDTO();
            template.setId(templateInfo.getTemplateId());
            template.setName(templateInfo.getTemplateName());
            template.setSmsId(smsId);
            template.setStatus(templateInfo.getStatus());
            template.setStatusName(template.getStatus().description);
            template.setTitle(templateInfo.getTemplateName());
            template.setContent(templateInfo.getContent());
            template.setParams(templateInfo.getParams());
            return template;
        }));
    }

    /**
     * 获取短信平台配置,当在数据库中找不到时,从配置文件找
     *
     * @param smsId 短信管理id
     * @return 短信平台配置
     */
    private SmsConfig loadConfig(String smsId) {
        SmsDO entity = this.service.getById(smsId);
        if (null == entity) {
            return Tools.Bean.copy(this.getFromProperties(smsId), SmsConfig.class);
        } else {
            return Tools.Bean.copy(entity, SmsConfig.class);
        }
    }

    /**
     * 根据配置smsId,从配置文件获取短信平台配置
     *
     * @param smsId 短信管理id
     * @return 短信平台配置
     */
    private SmsConfig getFromProperties(String smsId) {
        for (SmsProperties.Platform platform : this.properties.getPlatform()) {
            if (Tools.Str.equals(smsId, platform.getId())) {
                return Tools.Bean.copy(platform, SmsConfig.class);
            }
        }
        throw new FrameworkException("不支持的短信渠道");
    }
}
